package 行为型模式

import java.awt.Dimension
import java.awt.FlowLayout
import java.awt.Panel
import java.awt.event.ActionEvent
import javax.swing.JButton
import javax.swing.JCheckBox
import javax.swing.JFrame
import javax.swing.JLabel
import javax.swing.event.ChangeEvent


/**
 * 用一个中介对象来封装一系列的对象交互。中介者使各个对象不需要显式地相互引用，从而使其耦合松散，而且可以独立地改变它们之间的交互。
 */
/*
class OrderFrame(vararg names: String) : JFrame() {
    init {
        title = "Order"
        size = Dimension(460, 200)
        defaultCloseOperation = EXIT_ON_CLOSE
        contentPane.apply {
            layout = FlowLayout(FlowLayout.LEADING, 20, 20)
            add(JLabel("Use Mediator Pattern"))
            val checkBoxList = addCheckBox(*names)
            val selectAll = addButton("Select All")
            val selectNone = addButton("Select None")
            selectNone.isEnabled = false
            val selectInverse = addButton("Inverse Select")
            Mediator(checkBoxList, selectAll, selectNone, selectInverse)
            isVisible = true
        }


    }

    private fun addCheckBox(vararg names: String): ArrayList<JCheckBox> {
        val panel = Panel()
        panel.add(JLabel("Menu:"))
        val list = ArrayList<JCheckBox>()
        for (name in names) {
            val checkbox = JCheckBox(name)
            list.add(checkbox)
            panel.add(checkbox)
        }
        contentPane.add(panel)
        return list
    }

    private fun addButton(label: String): JButton {
        return JButton(label).also { contentPane.add(it) }
    }

}

class Mediator(
    private val checkBoxList: ArrayList<JCheckBox>,
    private val selectAll: JButton,
    private val selectNone: JButton,
    private val selectInverse: JButton
) {
    init {
        checkBoxList.forEach {
            it.addChangeListener(this::onCheckBoxChanged)
        }
        selectAll.addActionListener(this::onSelectAllClicked)
        selectNone.addActionListener(this::onSelectNoneClicked)
        selectInverse.addActionListener(this::onSelectInverseClicked)
    }

    private fun onCheckBoxChanged(event: ChangeEvent?) {
        var allChecked = true
        var allUnchecked = true
        for (checkBox in checkBoxList) {
            if (checkBox.isSelected) {
                allUnchecked = false
            } else {
                allChecked = false
            }
        }
        selectAll.isEnabled = !allChecked
        selectNone.isEnabled = !allUnchecked
    }

    private fun onSelectAllClicked(event: ActionEvent) {
        checkBoxList.forEach {
            it.isSelected = true
        }
        selectAll.isEnabled = false
        selectNone.isEnabled = true
    }

    private fun onSelectNoneClicked(event: ActionEvent) {
        checkBoxList.forEach {
            it.isSelected = false
        }
        selectAll.isEnabled = true
        selectNone.isEnabled = false
    }

    private fun onSelectInverseClicked(event: ActionEvent?) {
        checkBoxList.forEach {
            it.isSelected = !it.isSelected
        }
        onCheckBoxChanged(null)
    }
}

fun main() {
    OrderFrame("Hanburger", "Nugget", "Chip", "Coffee")
}*/


// 抽象中介者
interface Mediator {
    fun sendMessage(message: String, colleague: Colleague)
}

class MediatorImpl : Mediator {

    private val colleagues: MutableList<Colleague> = mutableListOf()

    fun add(colleague: Colleague) {
        colleagues.add(colleague)
    }

    override fun sendMessage(message: String, colleague: Colleague) {
        for (c in colleagues) {
            if (c != colleague) {
                c.receiveMessage(message)
            }
        }
    }

}

// 抽象同事类
abstract class Colleague {
    abstract fun receiveMessage(message: String)
    abstract fun sendMessage(message: String)
}

// 具体同事类
class ColleagueImpl(private val name: String, private val mediator: Mediator) : Colleague() {

    init {
        (mediator as? MediatorImpl)?.add(this)
    }

    override fun receiveMessage(message: String) {
        println("$name 收到消息：$message")
    }

    override fun sendMessage(message: String) {
        mediator.sendMessage(message, this)
    }

}

fun main(args: Array<String>) {
    val mediator = MediatorImpl()

    val colleagueA = ColleagueImpl("ColleagueA", mediator)
    val colleagueB = ColleagueImpl("ColleagueB", mediator)
    val colleagueC = ColleagueImpl("ColleagueC", mediator)

    colleagueA.sendMessage("Hello, everyone!")
    colleagueB.sendMessage("Nice to meet you!")
}